package com.bruce.tool.rpc.http.interceptor;

import com.bruce.tool.common.util.LogUtils;
import com.bruce.tool.common.util.string.StringUtils;
import com.bruce.tool.common.util.string.UniCodeUtils;
import com.bruce.tool.rpc.http.core.Https;
import com.bruce.tool.rpc.http.handler.LogInfo;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.http.HttpStatus;

import java.io.IOException;
import java.util.Objects;
import java.util.Optional;

@Slf4j
public class LogInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        long startTime = System.currentTimeMillis();
        LogInfo logInfo = Https.getLogInfo();
        StringBuilder requester = new StringBuilder()
                .append("{")
                .append("\"method\":\"").append(request.method()).append("\",")
                .append("\"url\":\"").append(request.url().toString()).append("\"")
                .append("}");
        logInfo.setRequestInfo(requester.toString());
        Response response = chain.proceed(chain.request());
        long duration = System.currentTimeMillis() - startTime;
        logInfo.setDuration(duration);
        MediaType mediaType = response.body().contentType();
        byte[] content = response.body().bytes();
        if(HttpStatus.OK.value() != response.code()){
            gatherErrorInfo(logInfo, new String(content), response);
        }else{
            gatherResponseInfo(logInfo, mediaType, content);
        }

        logInfo.setEnd("-----------------End:"+duration+"毫秒-----------------\n");

        /**打印日志逻辑**/
        print(logInfo);

        Https.removeLogInfo();

        return response.newBuilder()
                .body(okhttp3.ResponseBody.create(mediaType, content))
                .build();
    }

    private void print(LogInfo logInfo) {
        StringBuffer logInfoStr = new StringBuffer();
        if(StringUtils.isNotBlank(logInfo.getHeaderInfo()) ){
            logInfoStr.append("请求头:").append(logInfo.getHeaderInfo());
        }
        if(StringUtils.isNotBlank(logInfo.getRequestInfo()) ){
            logInfoStr.append("请求信息:").append(logInfo.getRequestInfo());
        }
        if(StringUtils.isNotBlank(logInfo.getBodyParams()) ){
            logInfoStr.append("body参数:").append(logInfo.getBodyParams());
        }
        if(StringUtils.isNotBlank(logInfo.getResponseInfo()) ){
            logInfoStr.append("返回结果:").append(logInfo.getResponseInfo());
        }
        if(null != logInfo.getDuration()){
            logInfoStr.append("耗时:").append(logInfo.getDuration()).append("ms");
        }
        LogUtils.info("{}",logInfoStr.toString());
    }

    /**校验http验证码**/
    private void gatherErrorInfo(LogInfo logInfo, String content, Response response) {
        if(StringUtils.isNotBlank(content) && content.length() > 1024){
            content = content.substring(0,1024);
        }
        String message = "HTTP状态码:" + response.code() + ",错误信息:" + content;
        logInfo.setResponseInfo(message);
    }

    private void gatherResponseInfo(LogInfo logInfo, MediaType mediaType, byte[] content) {
        String mediaTypeString = Optional.ofNullable(mediaType).orElse(MediaType.get("application/octet-stream")).toString();
        if( !mediaTypeString.contains("application/json")
                && !mediaTypeString.contains("text/xml")
                && !mediaTypeString.contains("text/html")
                && !mediaTypeString.contains("text/plain")
                && !mediaTypeString.contains("text/asp")){
            logInfo.setResponseInfo("请求类型:"+mediaTypeString+",请求大小:"+content.length);
        }else{
            String result = UniCodeUtils.toString(new String(content));
            logInfo.setResponseInfo(result);
        }
    }

}